#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int __SIZE = 1 << 18;
char ibuf[__SIZE], *iS, *iT;

#define ge (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, __SIZE, stdin), (iS == iT ? EOF : *iS++)) : *iS++)
#define ri read_int()
#define rl read_ll()
#define FILE(s) freopen(s "in", "r", stdin), freopen(s "out", "w", stdout)

template <typename T>
inline void read(T& x)
{
    char ch, t = 0;
    x = 0;
    while (!isdigit(ch = ge))
        t |= ch == '-';
    while (isdigit(ch))
        x = x * 10 + (ch ^ 48), ch = ge;
    x = t ? -x : x;
}
inline int read_int()
{
    int x;
    return read(x), x;
}
inline ll read_ll()
{
    ll x;
    return read(x), x;
}

template <typename T>
inline void chkmin(T& a, T b) { a = a < b ? a : b; }

const int MAXN = 132000;

int tot;
int fi[MAXN];
int ne[MAXN << 1];
int to[MAXN << 1];
int vl[MAXN << 1];

inline void Link(int u, int v, int w)
{
    tot++;
    to[tot] = v;
    vl[tot] = w;
    ne[tot] = fi[u];
    fi[u] = tot;
}

struct Node {
    ll a, b;

    Node() { }
    Node(ll a, ll b)
        : a(a)
        , b(b)
    {
    }

    friend bool operator<(Node a, Node b)
    {
        return a.a < b.a;
    }
} A[MAXN * 20], tmp[MAXN * 20];

int L[MAXN];
int R[MAXN];
int n;
int cnt;

inline void gb_Merge(int l1, int r1, int l2, int r2)
{
    int l = l1, r = r2, k = l1;
    while (l1 <= r1 && l2 <= r2) {
        if (A[l1] < A[l2])
            tmp[k++] = A[l1++];
        else
            tmp[k++] = A[l2++];
    }
    while (l1 <= r1)
        tmp[k++] = A[l1++];
    while (l2 <= r2)
        tmp[k++] = A[l2++];
    while (k > l)
        --k, A[k] = tmp[k];
}

inline void Merge(int x, int l, int r, ll lim)
{
    int pl1 = cnt + 1, pr1 = cnt;
    ll mi = 1LL << 61;
    for (int i = L[l], j = L[r] - 1; i <= R[l]; ++i) {
        while (j < R[r] && A[i].b + A[j + 1].a <= lim)
            ++j, mi = mi < A[j].b ? mi : A[j].b;
        if (j < L[r])
            continue;
        A[++pr1] = Node(A[i].a, mi);
    }
    cnt = pr1;
    int pl2 = cnt + 1, pr2 = cnt;
    mi = 1LL << 61, swap(l, r);
    for (int i = L[l], j = L[r] - 1; i <= R[l]; ++i) {
        while (j < R[r] && A[i].b + A[j + 1].a <= lim)
            ++j, mi = mi < A[j].b ? mi : A[j].b;
        if (j < L[r])
            continue;
        A[++pr2] = Node(A[i].a, A[j].b);
    }
    cnt = pr2, L[x] = pl1, R[x] = pr2;
    if (L[x] > R[x])
        return;
    gb_Merge(pl1, pr1, pl2, pr2);
    int Sum = 0;
    for (int i = L[x] + 1; i <= R[x]; ++i) {
        if (A[i].b >= A[L[x] + Sum].b)
            continue;
        else
            ++Sum, A[L[x] + Sum] = A[i];
    }
    cnt = R[x] = L[x] + Sum;
}

inline void dfs(int x, ll lim)
{
    if (!fi[x]) {
        L[x] = R[x] = ++cnt;
        A[cnt] = Node(0, 0);
    } else {
        L[x] = cnt + 1, R[x] = cnt;
        int val, Ls = to[fi[x]], Rs = to[ne[fi[x]]];

        dfs(Ls, lim), val = vl[fi[x]];
        if (L[Ls] > R[Ls])
            return;
        for (int i = L[Ls]; i <= R[Ls]; i++)
            A[i].a += val, A[i].b += val;

        dfs(Rs, lim), val = vl[ne[fi[x]]];
        if (L[Rs] > R[Rs])
            return;
        for (int i = L[Rs]; i <= R[Rs]; i++)
            A[i].a += val, A[i].b += val;

        Merge(x, Ls, Rs, lim);
    }
}

inline bool chk(ll lim)
{
    cnt = 0, dfs(1, lim);
    return L[1] <= R[1];
}

int main()
{
    FILE("trip.");
    n = ri;
    ll mx = 0;
    for (int i = 2; i <= n; i++) {
        int f = ri, v = ri;
        Link(f, i, v);
        mx += v;
    }
    ll l = 0, r = mx, res;
    while (l <= r) {
        ll mid = (l + r) >> 1;
        if (chk(mid))
            r = mid - 1, res = mid;
        else
            l = mid + 1;
    }
    printf("%lld\n", res);
    return 0;
}